/*
*  LLFileSerializer.h
*  
*
*  Created by Alexander Trutchenko on 11/02/12.
*  Copyright 2012 Free Team. All rights reserved.
*
*/

#ifndef __LL_FileSerializer_h__
#define __LL_FileSerializer_h__

#include "lid_lib/src/data_managment/LLSerialization.h"


#include <string>

namespace lidlib {

////////////////////////////////////////////////////////
// File descriptor mode

typedef enum 
{
	kLLFileDescriptorMode_read = 0,
	kLLFileDescriptorMode_rewrite,
	kLLFileDescriptorMode_add,

} llFileDescriptorMode; 

////////////////////////////////////////////////////////
//
/** LLFileDescriptor
*  
*/
////////////////////////////////////////////////////////

class LLFileDescriptor
{
protected:

	std::string _fullFilePath;
	llFileDescriptorMode _fdm;
	unsigned long _size;

private:
	LLFileDescriptor();

public:
	LLFileDescriptor(const std::string& fullFilePath, llFileDescriptorMode fdm)
		: _fullFilePath(fullFilePath)
		, _fdm(fdm)
		, _size(0)  {;}

	virtual ~LLFileDescriptor() {;}
 
public:
// Main interface
	const char* fullFilePath() const { return _fullFilePath.c_str(); }
	unsigned long size() const { return _size; }	

// Virtual interface
	virtual bool isValid() const = 0; 
	virtual bool readBlock(void* data, unsigned long size) = 0;
	virtual bool writeBlock(const void* data, unsigned long size) = 0;
};

////////////////////////////////////////////////////////
//
/** LLFileSerializer
*  
*/
////////////////////////////////////////////////////////

class LLFileSerializer : public LLArchive
{
	LLFileDescriptor* _descriptor;
	std::string _relativeFilePath;
	unsigned int _version;

private:
	//Depricate memory copy
	LLFileSerializer(const LLFileSerializer& serializer);
	LLFileSerializer& operator = (const LLFileSerializer& serializer);

public:
	LLFileSerializer(const std::string& relativeFilePath, bool readMode, unsigned int version = 0);
	
	virtual ~LLFileSerializer();

public:
	// Main interface
	bool isOpened() const { return (_descriptor != NULL); }
	const std::string& filePath() const { return _relativeFilePath; }

	bool readBlock(void* data, unsigned long size) const;
	bool writeBlock(const void* data, unsigned long size) const;

// LLArchive
	void operator &(unsigned char& data) { _readMode ? readBlock(&data, sizeof(unsigned char)) : writeBlock(&data, sizeof(unsigned char)); }
	void operator &(char& data) { _readMode ? readBlock(&data, sizeof(char)) : writeBlock(&data, sizeof(char)); }
	void operator &(unsigned long& data) { _readMode ? readBlock(&data, sizeof(unsigned long)) : writeBlock(&data, sizeof(unsigned long)); }
	void operator &(long& data) { _readMode ? readBlock(&data, sizeof(long)) : writeBlock(&data, sizeof(long)); }
	void operator &(unsigned int& data) { _readMode ? readBlock(&data, sizeof(unsigned int)) : writeBlock(&data, sizeof(unsigned int)); }
	void operator &(int& data) { _readMode ? readBlock(&data, sizeof(int)) : writeBlock(&data, sizeof(int)); }
	void operator &(float& data) { _readMode ? readBlock(&data, sizeof(float)) : writeBlock(&data, sizeof(float)); }
	void operator &(double& data) { _readMode ? readBlock(&data, sizeof(double)) : writeBlock(&data, sizeof(double)); }

private:
	LLFileDescriptor* createDescriptorPlatform(const std::string& fullFilePath, llFileDescriptorMode dm);
};


} // namespace lidlib

#endif //__LL_FileSerializer_h__
